Skip to content

feat: add RevenueCat integration templates and modular scaffolding support for native apps - #229

Merged
Marve10s merged 17 commits into
Marve10s:Developmentfrom
Alisha-21-cloud:feat/add-revenuecat-payments
Jul 4, 2026
Merged

feat: add RevenueCat integration templates and modular scaffolding support for native apps#229
Marve10s merged 17 commits into
Marve10s:Developmentfrom
Alisha-21-cloud:feat/add-revenuecat-payments

Conversation

@Alisha-21-cloud

@Alisha-21-cloud Alisha-21-cloud commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Add RevenueCat Payments Integration for Native Apps

Description

This PR introduces RevenueCat as a new payments provider for in-app purchases on native (Expo / React Native) applications.

Unlike the existing Polar integration (which is web-focused and Better-Auth dependent), RevenueCat is native-gated and auth-agnostic. It is exclusively offered when a native frontend is selected (native-bare, native-uniwind, or native-unistyles) and when a backend is present.

Key Features & Implementation Details

1. Core Integration & Configuration

  • Schema & Validation: Added revenuecat to PaymentsSchema.
    • Prompts conditionally offer RevenueCat only when a native frontend is present.
    • validatePaymentsCompatibility now correctly errors if RevenueCat is selected without a native frontend.
    • Added new Matrix oracle cases (e.g., payments-revenuecat-requires-native-frontend).
  • Web Stack-Builder: Added RevenueCat to apps/web with a native-frontend requirement constraint, mirroring how Polar gates on Better-Auth.

2. Convex Backend Support

  • Component Wiring: Integrates the convex-revenuecat component via app.use(revenuecat) in convex.config.ts.
  • Webhook Routing: Registers a RevenueCat webhook route (POST /webhooks/revenuecat).
    • Template Handler Logic: If Better-Auth is present, the webhook is appended to the existing Better-Auth http.ts. If no Better-Auth is used (e.g., Clerk or none), a standalone http.ts is generated to avoid clobbering routes.
  • Client API: Exposes a revenuecat.ts client with utilities like hasEntitlement, isSubscriber, and getActiveSubscriptions.
  • Other Backends: For backends other than Convex, the implementation gracefully falls back to a pure frontend React Native SDK integration (react-native-purchases), as RevenueCat handles subscription state independently.

3. Native Scaffolding & Components

  • Provider & SDK: Scaffolded a shared, auth-agnostic RevenueCatProvider and a lib/revenue-cat SDK layer.
  • UI Components: Added subscription-status-card and paywall-example components.
    • Fully styled across all three variants: standard StyleSheet (native-bare), NativeWind (native-uniwind), and unistyles (native-unistyles).
  • Layout Integration: The RevenueCatProvider is conditionally wrapped and mounted within each variant's app/_layout.tsx.

4. Environment Variables

  • Native (.env): Scaffolds EXPO_PUBLIC_REVENUECAT_IOS_KEY, EXPO_PUBLIC_REVENUECAT_ANDROID_KEY, and EXPO_PUBLIC_REVENUECAT_ENTITLEMENT_ID.
  • Convex (.env.local): Adds REVENUECAT_WEBHOOK_AUTH along with helpful setup comments for local development.

@vercel

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown

@Alisha-21-cloud is attempting to deploy a commit to the Ibrahim's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ effective changed lines (test files excluded in mixed PRs). labels Jun 17, 2026
@Marve10s

Copy link
Copy Markdown
Owner

Review — RevenueCat payments

Checked out the branch into a worktree, ran the full CI-equivalent suite against it, inspected every changed file, and cross-checked against docs/guidelines/adding-new-tool-options/. Every item below was verified against the actual branch code.

Verdict: Request changes

The feature is well-architected and passes all CI (types build, generate-templates in-sync, 95 snapshots, 603 cli-builder-sync, 55 payments tests, both typechecks, turbo lint, validate:tech-links, validate:tech-icons). But green CI is misleading here — there's one HIGH bug that breaks the headline feature for native-bare, and the weak tests are exactly why it passed.

What's good

  • Clean, auth-agnostic RevenueCatProvider + SDK layer (lib/revenuecat.ts): platform guards, idempotent configure, listener cleanup, purchase-cancellation handling, AppState refresh, correct useMemo deps.
  • Convex webhook routing is correct: appends to the better-auth http.ts when present, emits a standalone one otherwise — verified no clobber for clerk (clerk emits no http.ts).
  • Native gating is consistent across the CLI prompt, validatePaymentsCompatibility, and web getDisabledReason.
  • from "@expo/ui" (root) is a valid import for Expo SDK 56 (@expo/ui@56.0.18 exports a . entry → build/universal/index.d.ts). No need to rewrite to @expo/ui/swift-ui subpaths.

Findings

🔴 HIGH

  1. @expo/ui is never installed → native-bare is broken out of the box. payments/revenuecat/native/bare/components/{paywall-example,subscription-status-card}.tsx.hbs import @expo/ui, but it's in no package.json.hbs, not in add-deps.ts dependencyVersionMap, and not added by payments-deps.ts. A native-bare + revenuecat scaffold fails check-types (TS2307) and Metro bundling. Fix: add "@expo/ui": "~56.0.18" to dependencyVersionMap and add it to the native-bare branch of payments-deps.ts (uniwind/unistyles don't need it). Import paths are fine.

🟠 MEDIUM

  1. Convex variant never identifies the user → server-side entitlement queries silently return false. identifyUser/Purchases.logIn(userId) exists but is never called with the auth user anywhere, so the RevenueCat app_user_id stays anonymous and never matches the auth/Convex user id. The scaffolded isSubscriber/hasEntitlement queries (the point of the Convex backend support) won't work end-to-end. Wire identifyUser/logOutUser to the auth lifecycle, or document the requirement.
  2. Web builder emits a command the CLI rejects when the native frontend is removed. analyzeStackCompatibility (compatibility.ts) auto-strips polar/dodo to none when their requirement disappears, but there's no equivalent strip for revenuecat. Select native-bare + revenuecat, then remove the native frontend → the URL/command keeps --payments revenuecat, which the CLI then rejects via exitWithError. Add a strip block mirroring polar.
  3. ~2,742 lines of unrelated churn + scope-creep reformatting. constant.ts is reindented 2→4 spaces across ECOSYSTEMS/PRESET_TEMPLATES (the real change is only the 8-line revenuecat entry). Shared native templates (uniwind (drawer)/index.tsx.hbs, bare _layout.tsx.hbs, convex.config.ts.hbs, better-auth http.ts.hbs) were reformatted / EOF-newline-stripped, changing generated output (flush-left JSX, onPress={()=> {, split {isLoading &&) for users who never select RevenueCat. bun run check (oxfmt) reverts most of this — please keep the PR to the feature.
  4. Claimed tests don't exist + coverage is too weak. The description claims a payments-revenuecat-requires-native-frontend Matrix-oracle case — it doesn't exist anywhere, and there's no preflight/compatibility test for the native-required hard block. The 3 generation tests only call expectSuccess() (no semantic assertions). A single expect(nativePkg).toContain("@expo/ui") would have caught finding I forgot to merge this, Ralph didnt work :(  #1 (guideline "Runtime parity").
  5. All 10 new .hbs files lack trailing newlines (pre-commit checklist + Common Mistakes); generated user projects inherit it.

🟡 LOW / polish

  1. option-metadata.ts missing a revenuecat label override → humanizes to "Revenuecat" in metadata surfaces (siblings lemon-squeezy/dodo have overrides).
  2. tech-icons.ts missing the ICON_REGISTRY entry all 5 siblings have (works via fallback, but loses dark-mode icon adaptation).
  3. schemas.ts: ["revenuecat","polar",…] — missing space after the comma, and revenuecat inserted first instead of last.
  4. tech-resource-links.ts entry omits githubUrl (parity with stripe/polar/paddle).
  5. Non-convex backends get no server-side webhook (entitlements client-trusted only) — may be intended, but the asymmetry is undocumented.
  6. The description says RevenueCat requires "a backend present," but the code requires only a native frontend (no backend check) — description inaccuracy, not a bug.

Checked and dismissed (no action needed)

Broken simple-icons URL / validate CI failure (live CDN returns 200), snapshot breakage (native snapshots use hono; convex blocks gate out), lint failure, convex http.ts clobber for clerk, a better-auth provider-wrapping bug (one root _layout wraps all native apps), and any @expo/ui subpath-rewrite need — all verified non-issues.


The HIGH (#1) is the blocker; #2#4 are the next priority. Happy to provide a patch for the @expo/ui wiring and the auto-strip gap if useful.

@Alisha-21-cloud

Copy link
Copy Markdown
Contributor Author

@Marve10s Thankyou for the review..!! I will fix them and commit the changes very soon

@Marve10s
Marve10s changed the base branch from main to Development July 4, 2026 12:11
Marve10s added 2 commits July 4, 2026 15:38
…ating

- Rewrite native-bare paywall/subscription components to plain react-native
  primitives (View/Text/Pressable/StyleSheet). They previously imported from
  `@expo/ui`, which is never added as a dependency, so `native-bare + revenuecat`
  failed `tsc --noEmit` (TS2307). Matches the PR's stated 'standard StyleSheet'
  intent for native-bare and the unistyles variant's structure.
- Add a revenuecat branch to analyzeStackCompatibility so a web-only stack with
  payments=revenuecat is auto-normalized to none (mirrors polar), keeping the
  auto-adjust engine consistent with the prompt/getDisabledReason/CLI gates.
- Stop writing REVENUECAT_WEBHOOK_AUTH to apps/server/.env for non-convex
  backends (frontend-only path has no server webhook route; convex still gets it
  via packages/backend/.env.local).
The PR branch had reformatted (re-indented) the whole TECH_OPTIONS/ECOSYSTEMS
data in constant.ts, producing ~1370 lines of pure-whitespace churn against
Development for a single 8-line semantic change. Reset the file to Development
and re-add only the RevenueCat payments option, so the diff — and git blame —
stay clean and don't collide with concurrent constant.ts work.
@Marve10s
Marve10s merged commit 51ce4fe into Marve10s:Development Jul 4, 2026
17 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ effective changed lines (test files excluded in mixed PRs). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants